load("//bazel:tachyon.bzl", "if_gpu_is_configured")
load(
    "//bazel:tachyon_cc.bzl",
    "tachyon_cc_library",
    "tachyon_cc_unittest",
    "tachyon_openmp_num_threads_env",
)

package(default_visibility = ["//visibility:public"])

tachyon_cc_library(
    name = "evaluations_utils",
    hdrs = ["evaluations_utils.h"],
    deps = [
        "//tachyon/base:bits",
        "//tachyon/base:openmp_util",
        "//tachyon/base:profiler",
    ],
)

tachyon_cc_library(
    name = "fft_algorithm",
    srcs = ["fft_algorithm.cc"],
    hdrs = ["fft_algorithm.h"],
    deps = [
        "//tachyon:export",
        "//tachyon/base:logging",
    ],
)

tachyon_cc_library(
    name = "lagrange_interpolation",
    hdrs = ["lagrange_interpolation.h"],
    deps = [
        ":univariate_polynomial",
        "//tachyon/base:parallelize",
        "//tachyon/base:template_util",
    ],
)

tachyon_cc_library(
    name = "mixed_radix_evaluation_domain",
    hdrs = ["mixed_radix_evaluation_domain.h"],
    deps = [
        ":evaluations_utils",
        ":univariate_evaluation_domain",
        "//tachyon/base:profiler",
        "//tachyon/base/numerics:checked_math",
        "//tachyon/math/base/gmp:gmp_util",
        "//tachyon/math/finite_fields:prime_field_base",
        "@com_google_absl//absl/memory",
    ],
)

tachyon_cc_library(
    name = "naive_batch_fft",
    hdrs = ["naive_batch_fft.h"],
    deps = [
        ":two_adic_subgroup",
        "//tachyon/base:bits",
        "//tachyon/base:parallelize",
    ],
)

tachyon_cc_library(
    name = "radix2_evaluation_domain",
    hdrs = ["radix2_evaluation_domain.h"],
    deps = [
        ":evaluations_utils",
        ":radix2_twiddle_cache",
        ":two_adic_subgroup",
        ":univariate_evaluation_domain",
        "//tachyon/base:bits",
        "//tachyon/base:openmp_util",
        "//tachyon/base:parallelize",
        "//tachyon/base:profiler",
        "//tachyon/base/containers:container_util",
        "//tachyon/math/finite_fields:packed_prime_field_base",
        "//tachyon/math/matrix:matrix_types",
        "//tachyon/math/matrix:matrix_utils",
        "@com_google_absl//absl/memory",
        "@com_google_absl//absl/types:span",
        "@com_google_googletest//:gtest_prod",
        "@eigen_archive//:eigen3",
    ],
)

tachyon_cc_library(
    name = "radix2_twiddle_cache",
    hdrs = ["radix2_twiddle_cache.h"],
    deps = [
        "//tachyon/base:no_destructor",
        "//tachyon/base:openmp_util",
        "//tachyon/base:profiler",
        "@com_google_absl//absl/base:core_headers",
        "@com_google_absl//absl/container:flat_hash_map",
        "@com_google_absl//absl/synchronization",
    ],
)

tachyon_cc_library(
    name = "two_adic_subgroup",
    hdrs = ["two_adic_subgroup.h"],
    deps = [
        ":two_adic_subgroup_traits_forward",
        "//tachyon/base:optional",
        "//tachyon/math/matrix:matrix_types",
    ],
)

tachyon_cc_library(
    name = "two_adic_subgroup_traits_forward",
    hdrs = ["two_adic_subgroup_traits_forward.h"],
)

tachyon_cc_library(
    name = "univariate_evaluation_domain",
    hdrs = ["univariate_evaluation_domain.h"],
    deps = [
        ":evaluations_utils",
        ":fft_algorithm",
        ":univariate_evaluation_domain_forwards",
        ":univariate_evaluations",
        ":univariate_polynomial",
        "//tachyon/base:bits",
        "//tachyon/base:optional",
        "//tachyon/base:parallelize",
        "//tachyon/base:profiler",
        "//tachyon/base:range",
        "//tachyon/math/polynomials:evaluation_domain",
        "//tachyon/math/polynomials/univariate/icicle:fft_algorithm_conversion",
        "//tachyon/math/polynomials/univariate/icicle:icicle_ntt_holder",
    ],
)

tachyon_cc_library(
    name = "univariate_evaluation_domain_forwards",
    hdrs = ["univariate_evaluation_domain_forwards.h"],
)

tachyon_cc_library(
    name = "univariate_evaluation_domain_factory",
    hdrs = ["univariate_evaluation_domain_factory.h"],
    deps = [
        ":mixed_radix_evaluation_domain",
        ":radix2_evaluation_domain",
    ],
)

tachyon_cc_library(
    name = "univariate_evaluations",
    hdrs = [
        "univariate_evaluations.h",
        "univariate_evaluations_ops.h",
    ],
    deps = [
        ":univariate_evaluation_domain_forwards",
        "//tachyon/base:logging",
        "//tachyon/base:openmp_util",
        "//tachyon/base:optional",
        "//tachyon/base:parallelize",
        "//tachyon/base/buffer:copyable",
        "//tachyon/base/containers:container_util",
        "//tachyon/base/json",
        "//tachyon/math/base:parallelize_threshold",
        "//tachyon/math/polynomials:polynomial",
    ],
)

tachyon_cc_library(
    name = "univariate_polynomial",
    hdrs = [
        "support_poly_operators.h",
        "univariate_dense_coefficients.h",
        "univariate_polynomial.h",
        "univariate_polynomial_ops.h",
        "univariate_sparse_coefficients.h",
    ],
    deps = [
        ":univariate_evaluation_domain_forwards",
        "//tachyon/base:logging",
        "//tachyon/base:optional",
        "//tachyon/base:parallelize",
        "//tachyon/base:sort",
        "//tachyon/base/buffer:copyable",
        "//tachyon/base/containers:adapters",
        "//tachyon/base/containers:container_util",
        "//tachyon/base/containers:cxx20_erase",
        "//tachyon/base/json",
        "//tachyon/base/ranges:algorithm",
        "//tachyon/base/strings:string_util",
        "//tachyon/math/base:arithmetics_results",
        "//tachyon/math/base:parallelize_threshold",
        "//tachyon/math/polynomials:polynomial",
        "@com_google_absl//absl/hash",
        "@com_google_absl//absl/numeric:bits",
        "@com_google_absl//absl/types:span",
    ],
)

tachyon_cc_unittest(
    name = "univariate_unittests",
    srcs = [
        "lagrange_interpolation_unittest.cc",
        "radix2_evaluation_domain_unittest.cc",
        "univariate_dense_polynomial_unittest.cc",
        "univariate_evaluation_domain_unittest.cc",
        "univariate_evaluations_unittest.cc",
        "univariate_sparse_polynomial_unittest.cc",
    ],
    env = tachyon_openmp_num_threads_env(4),
    deps = [
        ":lagrange_interpolation",
        ":mixed_radix_evaluation_domain",
        ":naive_batch_fft",
        ":radix2_evaluation_domain",
        ":univariate_polynomial",
        "//tachyon/base:optional",
        "//tachyon/base/buffer:vector_buffer",
        "//tachyon/base/containers:contains",
        "//tachyon/base/containers:cxx20_erase",
        "//tachyon/base/functional:function_ref",
        "//tachyon/math/elliptic_curves/bls12/bls12_381:fr",
        "//tachyon/math/elliptic_curves/bn/bn254:fr",
        "//tachyon/math/elliptic_curves/bn/bn384_small_two_adicity:fq",
        "//tachyon/math/finite_fields/baby_bear",
        "//tachyon/math/finite_fields/koala_bear",
        "//tachyon/math/finite_fields/test:finite_field_test",
        "//tachyon/math/finite_fields/test:gf7",
        "@com_google_absl//absl/hash:hash_testing",
    ],
)

tachyon_cc_unittest(
    name = "univariate_gpu_unittests",
    srcs = if_gpu_is_configured(["univariate_evaluation_domain_gpu_unittest.cc"]),
    deps = [
        ":mixed_radix_evaluation_domain",
        ":radix2_evaluation_domain",
        "//tachyon/math/elliptic_curves/bn/bn254:fr",
        "//tachyon/math/finite_fields/test:finite_field_test",
    ],
)
